#ifndef MonitorServiceCfg_h__
#define MonitorServiceCfg_h__
#include "DbConnCfg.h"
#include "DbPoolConfig.h"
#include "LogConfig.h"


#include <string>
#include "tinyxml/tinyxml.h"

#pragma pack( push, 1 )

#define TAG_MONITORSERVICE			"MonitorService"	
#define TAG_THREADPOOL				"ThreadPool"
#define ATTR_THREADNUM				"ThreadNum"				
#define TAG_DBCONNLIST              "DBConnList"
#define TAG_MQSERVICELIST 			"MQServiceList"
#define TAG_RABBITMQ                "RabbitMq" 
#define ATTR_MQ_ADDR 				"IpAddr"
#define ATTR_MQ_PORT 				"Port"
#define ATTR_MQ_VHOST 				"VHost"
#define ATTR_MQ_USER 				"User"
#define ATTR_MQ_PASSWORD 			"Password"
#define ATTR_MQ_CONSUMETAG 			"ConsumerTag"
#define ATTR_MQ_EXCHANGE 			"Exchange"
#define ATTR_MQ_EXCHANGETYPE 		"ExchangeType"
#define ATTR_MQ_ROUTEKEY 			"RouteKey"
#define ATTR_MQ_QUEUE 				"Queue"

typedef struct __THREADPOOL_CFG
{
	unsigned int nThreadNum;
}THREADPOOL_CFG;

typedef struct __MQService_CFG
{
	std::string strAddr;
	unsigned int nPort;
	std::string strVHost;
	std::string strUser;
	std::string strPsw;
	std::string strConsumerTag;
	std::string strExchange;
	std::string strExchangeType;
	std::string strRouteKey;
	std::string strQueue;
}MQService_CFG;


typedef	struct __MONSRV_CONFIG
{
	THREADPOOL_CFG _threadpool;
	DBPOOL_CFG     _dbPool;
	std::vector<DBCONN_CFG> _vecDBConn;
	LOG_CONFIG      _log;
	std::vector<MQService_CFG> _vecMQServer;
}MONSRV_CONFIG;
#pragma pack( pop )

class MonServiceCfgParser
{
public:
	static bool XmlElement2MonSrvConfig(TiXmlElement* pMonSrv, MONSRV_CONFIG& cfg)
	{
		if (NULL == pMonSrv)
			return false;

		const char*	tagName = pMonSrv->Value();
		if( ( tagName == NULL ) || _stricmp( tagName, TAG_MONITORSERVICE ) )
			return false;

		int value(0);
		TiXmlElement* pThreadPool = pMonSrv->FirstChildElement(TAG_THREADPOOL);
		if (!pThreadPool)
			return false;
		pThreadPool->Attribute(ATTR_THREADNUM, &value);
		cfg._threadpool.nThreadNum = value;

		TiXmlElement* pDBPool = pMonSrv->FirstChildElement(TAG_DBPOOL);
		if (!DBPoolConfigParser::XmlElement2DBPoolCfg(pDBPool, cfg._dbPool))
			return false;

		TiXmlElement* pDBLst = pMonSrv->FirstChildElement(TAG_DBCONNLIST);
		if (!pDBLst)
			return false;
		
		TiXmlElement* pdbConn = pDBLst->FirstChildElement(TAG_DATABASE);
		while (pdbConn)
		{
			DBCONN_CFG dbconn;
			if (!DbConfigParser::XmlElement2DBCfg(pdbConn, dbconn))
				return false;

			cfg._vecDBConn.emplace_back(dbconn);
			pdbConn = pdbConn->NextSiblingElement(TAG_DATABASE);
		}

		TiXmlElement* pLog = pMonSrv->FirstChildElement(TAG_LOGCONFIG);
		if (!LogConfigParser::XmlElement2LogCfg(pLog, cfg._log))
			return false;

		TiXmlElement* pMQSvrLst = pMonSrv->FirstChildElement(TAG_MQSERVICELIST);
		if (!pMQSvrLst)
			return false;

		TiXmlElement* pRbtMq = pMQSvrLst->FirstChildElement(TAG_RABBITMQ);
		while (pRbtMq)
		{
			MQService_CFG rbtMq;

			const char *attr = pRbtMq->Attribute(ATTR_MQ_ADDR);
			if (attr)
				rbtMq.strAddr = attr;

			pRbtMq->Attribute(ATTR_MQ_PORT, &value);
			rbtMq.nPort = value;

			attr = pRbtMq->Attribute(ATTR_MQ_VHOST);
			if (attr)
				rbtMq.strVHost = attr;

			attr = pRbtMq->Attribute(ATTR_MQ_USER);
			if (attr)
				rbtMq.strUser = attr;

			attr = pRbtMq->Attribute(ATTR_MQ_PASSWORD);
			if (attr)
				rbtMq.strPsw = attr;

			attr = pRbtMq->Attribute(ATTR_MQ_CONSUMETAG);
			if (attr)
				rbtMq.strConsumerTag = attr;

			attr = pRbtMq->Attribute(ATTR_MQ_EXCHANGE);
			if (attr)
				rbtMq.strExchange = attr;

			attr = pRbtMq->Attribute(ATTR_MQ_EXCHANGETYPE);
			if (attr)
				rbtMq.strExchangeType = attr;

			attr = pRbtMq->Attribute(ATTR_MQ_ROUTEKEY);
			if (attr)
				rbtMq.strRouteKey = attr;

			attr = pRbtMq->Attribute(ATTR_MQ_QUEUE);
			if (attr)
				rbtMq.strQueue = attr;


			cfg._vecMQServer.emplace_back(rbtMq);
			pRbtMq = pRbtMq->NextSiblingElement(TAG_RABBITMQ);
		}




		return true;
	}

	static	bool	XmlString2MMonSrvConfig(const char* xmlString, MONSRV_CONFIG& cfg)
	{
		TiXmlDocument	doc;
		doc.Parse( xmlString );
		TiXmlElement*	pRoot = doc.RootElement();
		return XmlElement2MonSrvConfig(pRoot, cfg);
	}
};

#endif // MonitorServiceCfg_h__
